// 表的增删改查接口生成

function crud_handler(col_name) {
  return {
    async GET(req, reply) {
      let db_cols = this.mongo.db.collection(col_name);
      if (req.params?.id) {
        return {
          code: 0,
          msg: 'OK',
          data: await db_cols.findOne({ _id: new this.mongo.ObjectId(req.params.id) })
        };
      }
      let { page = 0, page_size = 50, ...qry } = req.query;
      let total = await db_cols.countDocuments(qry);
      let rs_data = [];
      if (total > 0) {
        rs_data = await db_cols.find(qry).limit(page_size).skip(page * page_size).toArray();
      }
      return {
        code: 0,
        msg: total > 0 ? 'OK' : 'No Data',
        page,
        page_size,
        total,
        data: rs_data
      };
    },
    async POST(req, reply) {
      let db_cols = this.mongo.db.collection(col_name);
      try {
        await db_cols.insertOne(req.body);
      } catch (error) {
        return { code: 2, msg: error.message, data: req.body };
      }
      return { code: 0, msg: 'OK', data: null };
    },
    async PUT(req, reply) {
      let db_cols = this.mongo.db.collection(col_name);
      try {
        await db_cols.updateOne({ _id: req.params?.id }, req.body);
      } catch (error) {
        return { code: 2, msg: error.message, data: req.body };
      }
      return { code: 0, msg: 'OK', data: null };
    },
    async DELETE(req, reply) {
      let db_cols = this.mongo.db.collection(col_name);
      try {
        await db_cols.deleteOne({ _id: req.params?.id });
      } catch (error) {
        return { code: 2, msg: error.message, data: req.body };
      }
      return { code: 0, msg: 'OK', data: null };
    },
  };
}

function filterMethods(api_cnf) {
  if (api_cnf.in && !!api_cnf.in[0]) {
    return api_cnf.in.map(k => k.toUpperCase());
  }
  let _un = api_cnf.un?.map(k => k.toUpperCase()) || [];
  return ['GET', 'POST', 'PUT', 'DELETE'].filter(v => !_un.includes(v));
}

// auto_db_api
export default (_tables = []) => {
  return async function(fastify, opts) {
    for (let tb of _tables) {
      let col_name = tb.name || tb.tabname;
      let _ins = filterMethods(tb.autoRestApi == true ? {} : tb.autoRestApi);
      console.log(`Auto DB Api : ${opts.prefix}/${col_name} - ${_ins.join(',')}`);
      if (_ins.includes('GET')) {
        await fastify.route({ url: `/${col_name}`, method: 'GET', handler: crud_handler(col_name).GET });
        await fastify.route({ url: `/${col_name}/:id`, method: 'GET', handler: crud_handler(col_name).GET });
      }
      if (_ins.includes('POST')) {
        await fastify.route({ url: `/${col_name}`, method: 'POST', handler: crud_handler(col_name).POST });
      }
      if (_ins.includes('PUT')) {
        await fastify.route({ url: `/${col_name}/:id`, method: 'PUT', handler: crud_handler(col_name).PUT });
      }
      if (_ins.includes('DELETE')) {
        await fastify.route({ url: `/${col_name}/:id`, method: 'DELETE', handler: crud_handler(col_name).DELETE });
      }
    }
  }
};
